import Vue from 'vue';
import { request } from '@access/core';
import {
  baseURL,
  contentType,
  debounce,
  invalidCode,
  noRoleCode,
  requestTimeout,
  successCode,
  tokenName,
} from '@/config/settings';
import store from '@/store';
import qs from 'qs';
import router from '@/router';
import apiList from '@/api/apiLibs';
import { isArray } from '@/utils/validate';

let loadingInstance;

/**
 * @author Mas0n kimpo2008@icloud.com
 * @description 判断当前url是否需要加loading
 * @param {*} config
 * @returns
 */
const needLoading = config => {
  let status = false;
  debounce.forEach(item => {
    if (Vue.prototype.$baseLodash.includes(config.url, item)) {
      status = true;
    }
  });
  return status;
};

/**
 * @author Mas0n kimpo2008@icloud.com
 * @description 处理code异常
 * @param {*} code
 * @param {*} msg
 */
const handleCode = (code, msg) => {
  switch (code) {
    case invalidCode:
      Vue.prototype.$baseMessage(msg || `后端接口${code}异常`, 'error');
      store.dispatch('user/resetAll').catch(() => {});
      break;
    case noRoleCode:
      router.push({ path: '/401' }).catch(() => {});
      break;
    default:
      Vue.prototype.$baseMessage(msg || `后端接口${code}异常`, 'error');
      break;
  }
};

const settings = {
  config: {
    baseURL,
    timeout: requestTimeout,
    headers: {
      'Content-Type': contentType,
    },
    //withCredentials: true,
  },
  apiList,
  reqHook(config) {
    if (store.getters['user/accessToken']) {
      config.headers[tokenName] = store.getters['user/accessToken'];
    }

    if (
      contentType === 'application/x-www-form-urlencoded;charset=UTF-8' &&
      config.data
    ) {
      config.data = qs.stringify(config.data);
    }

    if (needLoading(config)) {
      loadingInstance = Vue.prototype.$baseLoading();
    }
  },
  resHook(response) {
    if (loadingInstance) loadingInstance.close();
    if (response.status === 200) {
      const { code, data, msg } = response.data;
      if (code !== 0) {
        handleCode(code, msg);
        throw { code, msg };
      } else {
        return data;
      }
    } else {
      handleCode(response.status, response.statusText);
      throw {
        code: response.status,
        msg: response.statusText,
      };
    }
  },
  resErrHook(error) {
    if (loadingInstance) loadingInstance.close();
    const { response, message } = error;
    if (error.response && error.response.data) {
      const { status, data } = response;
      handleCode(status, data.msg || message);
      return Promise.reject(error);
    } else {
      let { message } = error;
      if (message === 'Network Error') {
        message = '后端接口连接异常';
      }
      if (message.includes('timeout')) {
        message = '后端接口请求超时';
      }
      if (message.includes('Request failed with status code')) {
        const code = message.substr(message.length - 3);
        message = '后端接口' + code + '异常';
      }
      Vue.prototype.$baseMessage(message || `后端接口未知异常`, 'error');
      return Promise.reject(error);
    }
  },
};
const instance = new request(settings);

export default instance;
